#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "ManejadorSemPisos.h"
#include "Constantes.h"
#include "Logger.h"
#include "Util.h"

/*
 * SemaforosPisos.cpp
 *
 *  Created on: Jun 26, 2012
 *      Author: maria
 */

#define PROCESS_NAME "MANEJADOR_SEM_PISOS"

using namespace std;

void ManejadorSemPisos::log(string message) {
	string name = PROCESS_NAME;
	string msg = name + ": " + message;
	logger->loggearLog(msg);
}

void ManejadorSemPisos::sync(string message) {
	string name = PROCESS_NAME;
	string msg = name + ": " + message;
	logger->loggearSynchro(msg);
}

void ManejadorSemPisos::debug(string message) {
	string name = PROCESS_NAME;
	string msg = name + ": " + message;
	logger->loggearDebug(msg);
}

void ManejadorSemPisos::crearSemaforos() {
	this->semPisos = (Semaforo**) malloc(
			sizeof(Semaforo*) * this->cantidadPisos);
	for (int i = 0; i < this->cantidadPisos; i++) {
		this->semPisos[i] = new Semaforo((char*) SEM_ARCHIVO_ASC_IN, (char) i,
				SEM_ASC_IN_CANTIDAD);
	}
	this->sync("Semáforos por piso creados.");
}

void ManejadorSemPisos::inicializar() {
	int valoresIniciales[6];

	valoresIniciales[SEM_UP_OPEN] = 0;
	valoresIniciales[SEM_UP_CLOSE] = 0;
	valoresIniciales[SEM_UP_ALL_NOTIFIED] = 0;
	valoresIniciales[SEM_DOWN_ALL_NOTIFIED] = 0;
	valoresIniciales[SEM_DOWN_OPEN] = 0;
	valoresIniciales[SEM_DOWN_CLOSE] = 0;

	for (int i = 0; i < this->cantidadPisos; i++)
		this->semPisos[i]->inicializar(valoresIniciales);
	this->sync("Semáforos por piso inicializados.");
}

void ManejadorSemPisos::liberarSemaforos() {
	this->sync("Liberamos los semáforos por piso.");
	for (int i = 0; i < this->cantidadPisos; i++) {
		this->semPisos[i]->eliminar_todos();
	}
	this->sync("Semáforos por piso liberados.");
}

ManejadorSemPisos::ManejadorSemPisos(int cantidadPisos) {
	this->logger = Logger::getInstance();
	this->cantidadPisos = cantidadPisos;
	this->crearSemaforos();
}

ManejadorSemPisos::~ManejadorSemPisos() {
	for (int i = 0; i < this->cantidadPisos; i++) {
		delete (this->semPisos[i]);
	}
	free(this->semPisos);
	this->sync("Semáforos por piso destruidos.");
}

void ManejadorSemPisos::esperoAscensor(int piso, char estado) {
	if (estado == ESPERANDO_SUBIR) {
		this->sync("P---> Sem Pisos = SEM_UP_OPEN");
		this->semPisos[piso]->p(SEM_UP_OPEN, 1);
	} else {
		this->sync("P---> Sem Pisos = SEM_DOWN_OPEN");
		this->semPisos[piso]->p(SEM_DOWN_OPEN, 1);
	}
}

void ManejadorSemPisos::esperoCierre(int piso, char estado) {
	this->sync("Persona espera que cierre las puertas el ascensor.");
	if (estado == ESPERANDO_SUBIR) {
		this->sync("V---> Sem Pisos = SEM_UP_CLOSE");
		this->semPisos[piso]->v(SEM_UP_CLOSE, 1);
		this->sync("P---> Sem Pisos = SEM_UP_ALL_NOTIFIED");
		this->semPisos[piso]->p(SEM_UP_ALL_NOTIFIED, 1);
	} else {
		this->sync("V---> Sem Pisos = SEM_DOWN_CLOSE");
		this->semPisos[piso]->v(SEM_DOWN_CLOSE, 1);
		this->sync("P---> Sem Pisos = SEM_DOWN_ALL_NOTIFIED");
		this->semPisos[piso]->p(SEM_DOWN_ALL_NOTIFIED, 1);
	}
}

void ManejadorSemPisos::abrir(int piso, char sentido, int cantidad) {
	if (sentido == SUBIENDO) {
		this->sync("V---> Sem Pisos = SEM_UP_OPEN");
		this->semPisos[piso]->v(SEM_UP_OPEN, cantidad);
		this->sync("P---> Sem Pisos = SEM_UP_CLOSE");
		this->semPisos[piso]->p(SEM_UP_CLOSE, cantidad);
	} else {
		this->sync("V---> Sem Pisos = SEM_DOWN_OPEN");
		this->semPisos[piso]->v(SEM_DOWN_OPEN, cantidad);
		this->sync("V---> Sem Pisos = SEM_DOWN_OPEN");
		this->semPisos[piso]->p(SEM_DOWN_CLOSE, cantidad);
	}

}

void ManejadorSemPisos::cerrar(int piso, char sentido, int cantidad) {
	if (sentido == SUBIENDO) {
		this->sync(
				"V---> Sem Pisos = SEM_UP_ALL_NOTIFIED en cantidad "
						+ Util::intToString(cantidad));
		this->semPisos[piso]->v(SEM_UP_ALL_NOTIFIED, cantidad);
	} else {
		this->sync(
				"V---> Sem Pisos = SEM_DOWN_ALL_NOTIFIED en cantidad "
						+ Util::intToString(cantidad));
		this->semPisos[piso]->v(SEM_DOWN_ALL_NOTIFIED, cantidad);
	}
}

